package com.mashibing.juc.c_026_01_ThreadPool;

import java.time.LocalTime;
import java.util.concurrent.*;

public class T14_MyRejectedHandler {

    public static void main(String[] args) throws Exception {

        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
                1, 3,
                0, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                new MyHandler());

        for (int i = 0; i <= 9; i++) {
            int finalI = i;
            Runnable runnable = () -> {
                try {
                    System.out.printf("\033[30m %s ===>> execute-[queue-%s]-%s \033[0m\n",
                            LocalTime.now(), poolExecutor.getQueue().size(), finalI);

                    TimeUnit.MILLISECONDS.sleep(2345);

                    System.out.printf("\033[32m %s ===>> execute-[queue-%s]-%s \033[0m\n",
                            LocalTime.now(), poolExecutor.getQueue().size(), finalI);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            };
            poolExecutor.execute(runnable);
            TimeUnit.MILLISECONDS.sleep(88);
        }

    }

    static class MyHandler implements RejectedExecutionHandler {

        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            if (executor.getQueue().size() < 10000) {
                try {
                    System.out.printf("\033[33m %s ===>> rejectedExecution ===>> %s \033[0m\n",
                            LocalTime.now(), r.hashCode());
                    TimeUnit.MILLISECONDS.sleep(1234);
                    System.out.printf("\033[34m %s ===>> executeAgain \033[0m\n", LocalTime.now());
                    executor.execute(r);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
